package com.hutu.service.biz.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hutu.constances.Constance;
import com.hutu.core.config.BusinessException;
import com.hutu.entity.system.Staff;
import com.hutu.mapper.biz.TableInfoMapper;
import com.hutu.model.biz.Column;
import com.hutu.model.biz.Module;
import com.hutu.model.biz.TableInfo;
import com.hutu.model.resp.Response;
import com.hutu.model.resp.ResponseVo;
import com.hutu.service.biz.ColumnService;
import com.hutu.service.biz.ModuleService;
import com.hutu.util.CommonUtil;
import com.hutu.util.JWTUtil;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hutu.service.biz.TableInfoService;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author admin
 * @since 2023-07-14
 */
@Service
public class  TableInfoServiceImpl extends ServiceImpl<TableInfoMapper,TableInfo> implements TableInfoService{

    @Resource
    private ColumnService columnService;

    @Resource
    private ModuleService moduleService;

    public ResponseVo add(TableInfo tableInfo){
        if(save(tableInfo)){
            return Response.success();
        }
        return Response.error();
    }

    @Transactional
    public ResponseVo deleteById(Integer id){
        if(removeById(id)){
            //级联删除字段
            LambdaQueryWrapper<Column> lambdaQueryWrapper = new LambdaQueryWrapper<Column>().eq(Column::getTableId, id);
            columnService.deleteByWrapper(lambdaQueryWrapper);
            return Response.success();
        }
        return Response.error();
    }

    public ResponseVo deleteBatch(List<Integer> ids){
        if(removeBatchByIds(ids)){
            return Response.success();
        }
        return Response.error();
    }


    public ResponseVo edit(TableInfo tableInfo){
        if(updateById(tableInfo)){
            return Response.success();
        }
        return Response.error();
    }


    public ResponseVo findById(Integer id){
        TableInfo tableInfo =getById(id);
        if(tableInfo !=null){
            return Response.success(tableInfo);
        }
        return Response.error();
    }


    public ResponseVo list(Integer current, Integer size, Integer pid ,String name) {
        IPage<TableInfo> config = new Page<>(current, size);
        QueryWrapper<TableInfo> wrapper = new QueryWrapper<>();
        //项目id
        if (Objects.nonNull(pid)) {
            wrapper.eq("pid", pid);
        }
        //关键字
        if(StrUtil.isNotBlank(name)){
            wrapper=new QueryWrapper<>();
            wrapper.like("table_name", StrUtil.format("%{}%",name));
            wrapper.or(w -> w.like("remark", StrUtil.format("%{}%",name)));
        }
        //权限,只能查看自己创建的
        wrapper.eq("create_user", JWTUtil.currentUser.get().getId());
        wrapper.orderByDesc("create_time");

        wrapper.select("id,table_Name,remark,create_user_name,pid," +
                "(select table_name from base_project where id = ht_table_info.pid) pname,package_name");
        IPage<TableInfo> page = page(config, wrapper);

        page.getRecords().forEach(e->{
            //根据 表ID查询所有的字段
            List<Column> columns = columnService.findByTableId(e.getId());
            String collect = columns.stream().map(Column::getColumnComment).collect(Collectors.joining(","));
            e.setFields(collect);
            //关键词高亮处理
//            if(e.getTableName() != null && StrUtil.isNotBlank(name)) {
//                String s = e.getTableName().replaceAll(name, "<font color=red>" + name + "</font>");
//                e.setTableName(s);
//            }
        });

        // 将响应数据填充到map中
        Map map = new HashMap();
        map.put("pages", page.getPages());
        map.put("total", page.getTotal());
        map.put("list", page.getRecords());
        return Response.success(map);
    }

    /**
    * 数据导出
    *
    * @param response
    * @return
    */
    public ResponseVo export(HttpServletResponse response)throws IOException{
        List<TableInfo> list=list();
        // 通过工具类创建对象，可以指定磁盘路径
        ExcelWriter writer=ExcelUtil.getWriter(true);
        // 一次性将list内的数据写入到excel，使用默认样式,强制输出标题
        writer.write(list,true);
        // 设置浏览器响应的格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String filename=URLEncoder.encode("数据","UTF-8");
        response.setHeader("Content-Disposition","attachment;filename="+filename+".xlsx");
        ServletOutputStream outputStream=response.getOutputStream();
        writer.flush(outputStream,true);
        outputStream.close();
        writer.close();
        return Response.success();
    }

    /**
     * 数据导入
     *
     * @param file
     * @return
     */
    public ResponseVo imp(MultipartFile file)throws IOException{
        InputStream inputStream=file.getInputStream();
        ExcelReader reader=ExcelUtil.getReader(inputStream);
        List<TableInfo> list=reader.readAll(TableInfo.class);
        // IService接口中的方法.批量插入数据
        if(saveBatch(list)){
            return Response.success();
        }
        return Response.error();
    }

    @Override
    @Transactional
    public ResponseVo addTableSchema(com.hutu.model.entity.core.TableInfo tableSchema) {
        TableInfo tableInfo = new TableInfo();
        tableInfo.setTableName(tableSchema.getTableName());
        tableInfo.setRemark(tableSchema.getTableComment());
        tableInfo.setPid(Integer.parseInt(tableSchema.getPid()));
        List<Column> columns = BeanUtil.copyToList(tableSchema.getColumns(), Column.class);
        save(tableInfo);
        columns.forEach(e -> {
            e.setTableId(tableInfo.getId());
            e.setTableName(tableInfo.getTableName());
            columnService.add(e);
        });
        //返回tableId
        return Response.success(tableInfo.getId());
    }

    @Override
    public ResponseVo createEntity(Integer id, String project) {
        Staff staff = JWTUtil.currentUser.get();
        List<Column> columns = columnService.findByTableId(id);
        TableInfo tableInfo = getById(id);
        String remark = tableInfo.getRemark();
        String tableName = tableInfo.getTableName();

        //java类型转换
        columns.forEach(e -> {
            e.setColumnType(CommonUtil.transferJdbcType2java(e.getColumnType()));
            e.setColumnName(CommonUtil.transferCamel(e.getColumnName()));
        });

        //查找对应项目的Entity模板
        Module module = moduleService.findByProject(project,"Entity");
        if(module == null) {
            throw new BusinessException("模板未找到！");
        }
        String template = module.getContent();
        VelocityContext context = new VelocityContext();

        String tableNameEn = CommonUtil.transformUnderscoreToCamelCase(tableName);
        // 注入参数
        context.put("author", staff.getName());
        context.put("date", DateUtil.now());
        context.put("tableName",tableName );
        context.put("entity",tableNameEn );
        context.put("tableComment", remark);
        context.put("packageEntity", tableInfo.getPackageName() + "." + tableNameEn.toLowerCase() + ".entity");
        context.put("tableFields", columns);



        StringWriter writer = new StringWriter();
        VelocityEngine engine = new VelocityEngine();
        engine.init();
        engine.evaluate(context, writer, "velocity", template);
        String result = writer.toString();
        ResponseVo vo = new ResponseVo();
        vo.setData(result);
        return Response.success(vo);
    }

    @Override
    public ResponseVo createVo(Integer id, String project) {
        Staff staff = JWTUtil.currentUser.get();
        List<Column> columns = columnService.findByTableId(id);
        TableInfo tableInfo = getById(id);
        String remark = tableInfo.getRemark();
        String tableName = tableInfo.getTableName();

        //java类型转换
        columns.forEach(e -> {
            e.setColumnType(CommonUtil.transferJdbcType2java(e.getColumnType()));
            e.setColumnName(CommonUtil.transferCamel(e.getColumnName()));
        });

        //查找对应项目的模板
        Module module = moduleService.findByProject(project,"Vo");
        String template = module.getContent();
        VelocityContext context = new VelocityContext();

        String tableNameEn = CommonUtil.transformUnderscoreToCamelCase(tableName);
        // 注入参数
        context.put("author", staff.getName());
        context.put("date", DateUtil.now());
        context.put("tableName",tableName );
        context.put("entity",tableNameEn );
        context.put("tableComment", remark);
        context.put("packageVo", tableInfo.getPackageName() + "." + tableNameEn.toLowerCase() + ".model." + tableNameEn.toLowerCase());
        context.put("tableFields", columns);



        StringWriter writer = new StringWriter();
        VelocityEngine engine = new VelocityEngine();
        engine.init();
        engine.evaluate(context, writer, "velocity", template);
        String result = writer.toString();
        ResponseVo vo = new ResponseVo();
        vo.setData(result);
        return Response.success(vo);
    }

    @Override
    public ResponseVo createMapper(Integer id, String project) {
        Staff staff = JWTUtil.currentUser.get();
        List<Column> columns = columnService.findByTableId(id);
        TableInfo tableInfo = getById(id);
        String remark = tableInfo.getRemark();
        String tableName = tableInfo.getTableName();

        //java类型转换
        columns.forEach(e -> {
            e.setColumnType(CommonUtil.transferJdbcType2java(e.getColumnType()));
            e.setColumnName(CommonUtil.transferCamel(e.getColumnName()));
        });

        //查找对应项目的模板
        Module module = moduleService.findByProject(project,"Mapper.java");
        String template = module.getContent();
        VelocityContext context = new VelocityContext();

        String tableNameEn = CommonUtil.transformUnderscoreToCamelCase(tableName);
        // 注入参数
        context.put("author", staff.getName());
        context.put("date", DateUtil.now());
        context.put("tableName",tableName );
        context.put("entity",tableNameEn );
        context.put("tableComment", remark);
        context.put("packageMapper", tableInfo.getPackageName() + "." + tableNameEn.toLowerCase() + ".mapper");
        context.put("packageEntity", tableInfo.getPackageName() + "." + tableNameEn.toLowerCase() + ".entity");
        context.put("tableFields", columns);



        StringWriter writer = new StringWriter();
        VelocityEngine engine = new VelocityEngine();
        engine.init();
        engine.evaluate(context, writer, "velocity", template);
        String result = writer.toString();
        ResponseVo vo = new ResponseVo();
        vo.setData(result);
        return Response.success(vo);
    }

    @Override
    public ResponseVo createMapper2(Integer id, String project) {
        Staff staff = JWTUtil.currentUser.get();
        List<Column> columns = columnService.findByTableId(id);
        TableInfo tableInfo = getById(id);
        String remark = tableInfo.getRemark();
        String tableName = tableInfo.getTableName();

        //java类型转换
        columns.forEach(e -> {
            e.setColumnType(CommonUtil.transferJdbcType2java(e.getColumnType()));
            e.setColumnName(CommonUtil.transferCamel(e.getColumnName()));
        });

        //查找对应项目的模板
        Module module = moduleService.findByProject(project,"Mapper.xml");
        String template = module.getContent();
        VelocityContext context = new VelocityContext();

        String tableNameEn = CommonUtil.transformUnderscoreToCamelCase(tableName);
        // 注入参数
        context.put("author", staff.getName());
        context.put("date", DateUtil.now());
        context.put("tableName",tableName );
        context.put("entity",tableNameEn );
        context.put("tableComment", remark);
        context.put("packageMapper", tableInfo.getPackageName() + "." + tableNameEn.toLowerCase() + ".mapper");
        context.put("packageEntity", tableInfo.getPackageName() + "." + tableNameEn.toLowerCase() + ".entity");
        context.put("tableFields", columns);



        StringWriter writer = new StringWriter();
        VelocityEngine engine = new VelocityEngine();
        engine.init();
        engine.evaluate(context, writer, "velocity", template);
        String result = writer.toString();
        ResponseVo vo = new ResponseVo();
        vo.setData(result);
        return Response.success(vo);
    }

    @Override
    public void addBlankRow(Integer tid) {
        Column column = new Column();
        column.setTableId(tid);
        columnService.add(column);
    }


}




